package com.ljkj.blockpay.network;

import com.ljkj.blockpay.basedata.BuildConfig;
import com.ljkj.blockpay.network.customthread.ThreadPools;
import com.ljkj.blockpay.network.interceptor.CacheInterceptor;
import com.ljkj.blockpay.network.interceptor.CacheNetWorkInterceptor;
import com.ljkj.blockpay.network.interceptor.HttpLoggingInterceptor;
import com.ljkj.blockpay.network.interceptor.HttpNetParamsInterceptor;
import com.ljkj.blockpay.network.interceptor.RetryInterceptor;
import com.ljkj.blockpay.network.log.LogInterceptor;
import com.ljkj.blockpay.util.GlobalContext;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.schedulers.Schedulers;
import okhttp3.Cache;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.Dispatcher;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;


public class ApiServiceFactory {

    private final static int CONNECT_TIME_OUT = 20;
    private final static int READ_TIME_OUT = 30;
    private final static int WRITE_TIME_OUT = 30;

    private static OkHttpClient mOkHttpClient;

    public static <T> T createApiServiceImpl(Class<T> apiServiceClass) {
        mOkHttpClient = buildOkHttpClient();
        return createApiServiceImpl(apiServiceClass, getBaseUrl(), mOkHttpClient);
    }

    private static OkHttpClient buildOkHttpClient() {
        long MAX = 50 * 1024 * 1024;//设置缓存最大内存
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .sslSocketFactory(SSLFactory.sslContext.getSocketFactory())
                .hostnameVerifier(SSLFactory.DO_NOT_VERIFY)
                .dispatcher(new Dispatcher(ThreadPools.COMPUTATION_THREAD_POOL.get()))
                .writeTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
                .readTimeout(READ_TIME_OUT, TimeUnit.SECONDS)
                .connectTimeout(WRITE_TIME_OUT, TimeUnit.SECONDS)
                .cookieJar(new CookieJar() {
                    private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>(16);
                    @Override
                    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
                        cookieStore.put(HttpUrl.parse(url.host()), cookies);
                    }

                    @Override
                    public List<Cookie> loadForRequest(HttpUrl url) {
                        List<Cookie> cookies = cookieStore.get(url.host());
                        return cookies != null ? cookies : new ArrayList<Cookie>();
                    }
                })
//                .cache(new Cache(new File(GlobalContext.getAppContext().getExternalFilesDir("giftcache").getAbsolutePath()),MAX))
                .followRedirects(false);
//        builder.addInterceptor(new CacheInterceptor());
        builder.addNetworkInterceptor(new CacheNetWorkInterceptor());
        builder.addInterceptor(new HttpNetParamsInterceptor());
//        builder.addInterceptor(new HttpLoggingInterceptor());
        builder.addInterceptor(new LogInterceptor());
        builder.addInterceptor(new RetryInterceptor());
        return builder.build();
    }


    private static <T> T createApiServiceImpl(Class<T> apiServiceClass, String endPoint, OkHttpClient okHttpClient) {
        return new Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl(endPoint)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
                .build()
                .create(apiServiceClass);
    }

    private static String getBaseUrl() {
        return BuildConfig.BASE_API_SERVICE;
    }

    //此处可以根据业务需求获取当前httpClient
    public static OkHttpClient getOkHttpClient() {
        return mOkHttpClient == null ? buildOkHttpClient() : mOkHttpClient;
    }
}
